package main;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import jxl.read.biff.BiffException;
import base.Parameter;
import base.ReferenceParameter;
import factory.Job;
import gene.Gene;
import gene.GeneManager;
import util.Log;
import data.Export;
import data.Import;

public class Main {
	public static void main(String[] args) throws CloneNotSupportedException {

		Log.setType("C");

		Parameter parameters = new Parameter();

		parameters.addParameter(Parameter.TYPE_ARITY, "2");
		parameters.addParameter(Parameter.TYPE_ROOTNODE_ARITY, "2");
		parameters.addParameter(Parameter.TYPE_CROSSOVER_RATE, "0.8");
		parameters.addParameter(Parameter.TYPE_DEPTH, "0");
		parameters.addParameter(Parameter.TYPE_GENE_POPULATION, "10");
		parameters.addParameter(Parameter.TYPE_MAX_DEPTH, "2");
		parameters.addParameter(Parameter.TYPE_MUTATION_RATE, "0.1");
		parameters.addParameter(Parameter.TYPE_REPRODUCTION_RATE, "0.1");
		parameters.addParameter(Parameter.TYPE_GENERATION, "5");
		
		// parameter 입력
	
		List<ReferenceParameter> rpList = new ArrayList<ReferenceParameter>();
		
		ReferenceParameter rp = new ReferenceParameter(14, 3, new Job("Job 0", 4), new Job("Job 1", 5), new Job("Job 2", 7), new Job("Job 3", 6), new Job("Job 4", 10), new Job("Job 5", 3), new Job("Job 6", 3), new Job("Job 7", 1));
		ReferenceParameter rp1 = new ReferenceParameter(42, 5, new Job("0", 2), new Job("0", 4), new Job("0", 5), new Job("0", 7), new Job("0", 8), new Job("0", 9), new Job("0", 10),
				new Job("0", 13), new Job("0", 17), new Job("0", 20), new Job("0", 13), new Job("0", 16), new Job("0", 3), new Job("0", 5), new Job("0", 7), new Job("0", 9), new Job("0", 12),
				new Job("0", 13), new Job("0", 17), new Job("0", 2));

		rpList.add(rp);
		rpList.add(rp1);

		int referenceCount = rpList.size();

		String referCount = Integer.toString(referenceCount);

		parameters.addParameter(Parameter.TYPE_REFERENCE_SIZE, referCount);
		Log.debug("start");

		GeneManager gm = new GeneManager();
		gm.generation(parameters, rpList);

		for(int i =0; i<gm.getBestGeneList().size();i++){
		Log.debug("root node " + 	gm.getBestGeneList().get(i).getRootNode().getName());

		if (	gm.getBestGeneList().get(i).getRootNode().getBranches() != null) {
			for (int j = 0; j < 	gm.getBestGeneList().get(i).getRootNode().getArity(); j++) {
				
				Log.debug("root node First Arity "+ j +"  "+ 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getName());

				if (	gm.getBestGeneList().get(i).getRootNode().getChild(j).getBranches() != null) {
					for (int k = 0; k < 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getArity(); k++) {
						Log.debug("root node second Arity " + k +"  " + 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getName());

						if (	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getBranches() != null) {
							for (int l = 0; l < 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getArity(); l++) {
								Log.debug("root node third Arity " + l + "   " + gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getName());

								if (	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getBranches() != null) {
									for (int m = 0; m < 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getArity(); m++) {
										Log.debug("root node forth Arity " + m +"     "+ gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getName());

										if (	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getBranches() != null)
											for (int n = 0; n < 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getArity(); n++) {
												Log.debug("root node forth Arity " + n +"    "
														+ 	gm.getBestGeneList().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getChild(n).getName());
											}
									}
								}
							}
						}
					}
				}

			}
		}
		}
		
		for (int i = 0; i < gm.getBestGeneList().size(); i++) {
			Log.debug("Generation " + i + " 베스트 진 " + gm.getBestGeneList().get(i).getName()+" "+" 평균 에버리지 "+ gm.getBestGeneList().get(i).getAverageFiness() + " " +" 피트니스  "+gm.getBestGeneList().get(i).scheduleList.get(0).getFitness()+"  "+gm.getBestGeneList().get(i).scheduleList.get(1).getFitness());
		}
		
//		for (int i = 0; i < gm.getGenePopulation().size(); i++) {
//			Log.debug(gm.getGenePopulation().get(i).getName() + "   =========maxDepth ========" + gm.getGenePopulation().get(i).getMaxHeight());
//		}
//		for (int i = 0; i < gm.getGenePopulation().size(); i++) {
//			Log.debug("root node " + gm.getGenePopulation().get(i).getRootNode().getName());
//
//			if (gm.getGenePopulation().get(i).getRootNode().getBranches() != null) {
//				for (int j = 0; j < gm.getGenePopulation().get(i).getRootNode().getArity(); j++) {
//					
//					Log.debug("root node First Arity "+ j +"  "+ gm.getGenePopulation().get(i).getRootNode().getChild(j).getName());
//
//					if (gm.getGenePopulation().get(i).getRootNode().getChild(j).getBranches() != null) {
//						for (int k = 0; k < gm.getGenePopulation().get(i).getRootNode().getChild(j).getArity(); k++) {
//							Log.debug("root node second Arity " + k +"  " + gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getName());
//
//							if (gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getBranches() != null) {
//								for (int l = 0; l < gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getArity(); l++) {
//									Log.debug("root node third Arity " + l + "   " + gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getName());
//
//									if (gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getBranches() != null) {
//										for (int m = 0; m < gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getArity(); m++) {
//											Log.debug("root node forth Arity " + m +"     "+ gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getName());
//
//											if (gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getBranches() != null)
//												for (int n = 0; n < gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getArity(); n++) {
//													Log.debug("root node forth Arity " + n +"    "
//															+ gm.getGenePopulation().get(i).getRootNode().getChild(j).getChild(k).getChild(l).getChild(m).getChild(n).getName());
//												}
//										}
//									}
//								}
//							}
//						}
//					}
//
//				}
//			}
//		}
//
//		for (int i = 0; i < gm.getGenePopulation().size(); i++) {
//			Log.debug("=================================gene================" + gm.getGenePopulation().get(i).getName());
//			for (int j = 0; j < gm.getGenePopulation().get(i).scheduleList.size(); j++) {
//				Log.debug("=================================schedule================" + gm.getGenePopulation().get(i).scheduleList.get(j).getName());
//				for (int k = 0; k < gm.getGenePopulation().get(i).scheduleList.get(j).getMachineIndex().size(); k++) {
//					for (int t = 0; t < gm.getGenePopulation().get(i).scheduleList.get(j).getMachineIndex().get(k).getMachineSchedule().size(); t++) {
//						Log.debug("Machine " + k + " " + "Job " + gm.getGenePopulation().get(i).scheduleList.get(j).getMachineIndex().get(k).getMachineSchedule().get(t).getJobIndex() + " PT "
//								+ gm.getGenePopulation().get(i).scheduleList.get(j).getMachineIndex().get(k).getMachineSchedule().get(t).getProcessingTime());
//					}
//					Log.debug("Machine " + k + " " + "Total working time " + gm.getGenePopulation().get(i).scheduleList.get(j).getMachineIndex().get(k).getTotalWorkingTime());
//				}
//				Log.debug("Schedule " + j + " Cmax " + gm.getGenePopulation().get(i).scheduleList.get(j).getCmax());
//				Log.debug("Current Time " + gm.getGenePopulation().get(i).scheduleList.get(j).getCurrentTime());
//			}
//		}

//		
		Export export = new Export();
		export.export(gm);
		Log.debug("end");

	}
}
